package com.apchernykh.rozhlasapp.services;

import com.apchernykh.rozhlasapp.ui.RozhlasAppBaseFragmentActivity;
import com.apchernykh.rozhlasapp.utils.ConditionalLog;
import com.apchernykh.rozhlasapp.utils.PreferencesCache;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

public abstract class InetNotifiedService extends NotifiedService implements
		IInetConnectivityInfo, IInetConnectivityChangeListener {

	@Override
	public void signalInetRestored() {
		mConnectivity.signalInetRestored();
	}

	@Override
	public void signalInetFailure() {
		mConnectivity.signalInetFailure();
	}

	@Override
	public boolean isDownloadAllowed() {
		// TODO Auto-generated method stub
		return mConnectivity.isInetAvailable();
	}

	@Override
	public boolean isInetAvailable() {
		return mConnectivity.isInetAvailable();
	}

	public class InetConnectivityState extends BroadcastReceiver {
		/**
		 * 
		 */
		static final long INET_RETRY_TIMEOUT = 60000;
		public long mInetNextRetry = Long.MAX_VALUE;
		private boolean mInetIsWiFi = false;
		public boolean mInetIsAvailable = false;
		public long mBandwidthAvailable = 0;

		public void signalInetFailure() {
			mInetIsAvailable = false;
			mInetNextRetry = System.currentTimeMillis() + INET_RETRY_TIMEOUT;
			notifyInetChange();
		}

		// public void signalInetConnected(long iBandwidth) {
		// mInetIsAvailable = true;
		// mBandwidthAvailable = iBandwidth;
		// }

		public void signalInetRestored() {
			mInetNextRetry = Long.MAX_VALUE;
			if (!mInetIsAvailable) {
				mInetIsAvailable = true;
				resetConnectedStatus();
			}

		}

		public boolean isInetAvailable() {
			// mPreferences.mOnWiFiOnly
			if (mPreferences.mOnWiFiOnly && !mInetIsWiFi) {
				// handle the preference "enable on WiFi only"
				return false;
			}

			if (!mInetIsAvailable) {
				// Retry mechanism for dead zones. Sometimes, the signal is
				// weak, but is said to have high bandwidth
				if (System.currentTimeMillis() > mInetNextRetry) {
					mInetIsAvailable = true;
					notifyInetChange();
				}
			}
			return mInetIsAvailable;
		}

		public void notifyInetChange() {
			onInetConnectivityChange(isInetAvailable());
		}

		public void resetWiFiStatus() {
			mInetIsWiFi = false;
			Object aServiceObj = getSystemService(Context.CONNECTIVITY_SERVICE);
			if (aServiceObj != null
					&& aServiceObj instanceof ConnectivityManager) {
				ConnectivityManager mConnectivityManager = (ConnectivityManager) aServiceObj;
				NetworkInfo aInfo = mConnectivityManager.getActiveNetworkInfo();
				if (aInfo != null) {
					mInetIsWiFi = (ConnectivityManager.TYPE_WIFI == aInfo
							.getType());
				}
			}
		}

		public void resetConnectedStatus() {
			ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
			Object aServiceObj = getSystemService(Context.CONNECTIVITY_SERVICE);
			if (aServiceObj != null
					&& aServiceObj instanceof ConnectivityManager) {

				NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
				if (activeNetwork == null) {
					return;
				}
				mInetIsAvailable = activeNetwork.isConnectedOrConnecting();
			} else {
				mInetIsAvailable = true;
			}
		}

		@Override
		public void onReceive(Context iContext, Intent intent) {
			mInetNextRetry = Long.MAX_VALUE;

			mInetIsAvailable = !intent.getBooleanExtra(
					ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);

			resetWiFiStatus();
			notifyInetChange();
		}

	}

	@Override
	public void onCreate() {
		ConditionalLog.e("InetNotifiedService.onCreate()");
		registerReceiver(mConnectivity, new IntentFilter(
				ConnectivityManager.CONNECTIVITY_ACTION));
		mConnectivity.resetWiFiStatus();
		mConnectivity.resetConnectedStatus();
		mPreferences.refresh(this);
		onInetConnectivityChange(mConnectivity.isInetAvailable());
		RozhlasAppBaseFragmentActivity.mApplicationModel.mOnInetStateListener
				.onInetStatusChange(mConnectivity.isInetAvailable());
		super.onCreate();
	}

	protected final InetConnectivityState mConnectivity = new InetConnectivityState();
	protected final PreferencesCache mPreferences = new PreferencesCache();

	@Override
	public void onDestroy() {
		unregisterReceiver(mConnectivity);
		super.onDestroy();
	}
}